package org.mozhu.mboot.admin.config;

import com.google.common.base.Splitter;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.mozhu.mboot.core.config.ApplicationConfiguration;
import org.mozhu.mboot.core.i18n.CookieSessionLocaleResolver;
import org.mozhu.mboot.core.i18n.LocaleChangeInterceptor;
import org.mozhu.mboot.core.web.PerformanceListener;
import org.mozhu.mboot.core.web.bind.resolver.PageableMethodArgumentResolver;
import org.mozhu.mboot.core.web.bind.resolver.SearchableMethodArgumentResolver;
import org.mozhu.mboot.core.web.converter.String2DateConverter;
import org.mozhu.mboot.core.web.converter.String2LocalDateConverter;
import org.mozhu.mboot.core.web.filter.HttpLoggingFilter;
import org.mozhu.mboot.core.web.interceptor.CommonDataInterceptor;
import org.mozhu.mboot.core.web.interceptor.PjaxInterceptor;
import org.mozhu.mboot.core.web.resource.WebResourceConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;
import java.util.Set;

@Configuration
@Slf4j
public class WebConfiguration implements WebMvcConfigurer {

    public static final String STATIC_RESOURCE_PATTERN = "/status.ci,/theme/assets/**,/resource/**,/static/**,/**/*.js,/**/*.css,/**/*.jpg,/**/*.png,/**/*.gif,/**/*.ico";
    public static final Set<String> STATIC_RESOURCE_PATTERNS = Sets.newHashSet(Splitter.on(",").omitEmptyStrings().trimResults().splitToList(STATIC_RESOURCE_PATTERN));

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new PageableMethodArgumentResolver());
        argumentResolvers.add(new SearchableMethodArgumentResolver());
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
        registry.addInterceptor(commonDataInterceptor());
        registry.addInterceptor(pjaxInterceptor());
    }

    @Bean
    public CommonDataInterceptor commonDataInterceptor() {
        CommonDataInterceptor commonDataInterceptor = new CommonDataInterceptor();
        commonDataInterceptor.setExclusions(STATIC_RESOURCE_PATTERNS);
        return commonDataInterceptor;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setExclusions(STATIC_RESOURCE_PATTERNS);
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }

    @Bean
    public PjaxInterceptor pjaxInterceptor() {
        return new PjaxInterceptor();
    }

    @Bean
    public CookieSessionLocaleResolver localeResolver() {
        CookieSessionLocaleResolver cookieSessionLocaleResolver = new CookieSessionLocaleResolver();
        cookieSessionLocaleResolver.setSkipResolveLocaleFromSessionUrls(Sets.newHashSet("/login"));
        return cookieSessionLocaleResolver;
    }

    @Bean
    public HttpLoggingFilter httpLoggingFilter() {
        HttpLoggingFilter filter = new HttpLoggingFilter();
        filter.setIncludePayload(true);
        filter.setIncludeClientInfo(false);
        filter.setIncludeQueryString(true);
        filter.setBeforeMessagePrefix("");
        filter.setBeforeMessageSuffix("");
        filter.setAfterMessagePrefix("");
        filter.setAfterMessageSuffix("");
        filter.setExclusions(STATIC_RESOURCE_PATTERNS);
        filter.setMaxPayloadLength(Integer.MAX_VALUE);
        return filter;
    }

    @Bean
    public PerformanceListener requestListener() {
        return new PerformanceListener(STATIC_RESOURCE_PATTERNS);
    }
}
